/*
	File:		EventSystem.cpp
	Author:		Ben Feldmann
	Purpose:	Handle events in the game
*/

#include "EventSystem.h"


EventSystem* EventSystem::GetInstance() 
{
	//return eventSystem;
	static EventSystem instance;
	return &instance;
}

void EventSystem::DispatchEvent(Event* newEvent)
{
	pair<multimap<string, IListener*>::iterator, 
		 multimap<string, IListener*>::iterator> range;

	range = clients.equal_range(newEvent->GetEventID());

	multimap<string, IListener*>::iterator iter;
	for(iter = range.first; iter != range.second; iter++)
	{
		(*iter).second->HandleEvent(newEvent);
	}
}

bool EventSystem::AlreadyRegistered(string eventID, IListener* client)
{
	bool isRegistered = false;

	pair<multimap<string, IListener*>::iterator,
		 multimap<string, IListener*>::iterator> range;

	range = clients.equal_range(eventID);

	multimap<string, IListener*>::iterator iter;
	for(iter = range.first; iter != range.second; iter++)
	{
		if((*iter).second == client)
		{
			isRegistered = true;
			break;
		}
	}

	return isRegistered;
}

void EventSystem::RegisterClient(string eventID, IListener* client) 
{
	if (client == nullptr || AlreadyRegistered(eventID, client))	
		return;

	clients.insert(make_pair(eventID, client));
}

void EventSystem::UnregisterClientAll(IListener* client) 
{
	multimap<string, IListener*>::iterator iter = clients.begin();

	while(iter != clients.end())
	{
		if((*iter).second == client)
		{
			iter = clients.erase(iter);
		}
		else
			iter++;
	}
}

void EventSystem::SendEvent(string eventID, void* data, void* data2) 
{
	Event newEvent(eventID, data);

	events.push_back(newEvent);
}



void EventSystem::ProcessEvents() 
{
	while(events.size() != 0)
	{
		DispatchEvent(&events.front());
		events.pop_front();
	}
}

void EventSystem::ClearEvents() 
{
	events.clear();
}

void EventSystem::ShutdownEventSystem() 
{
	clients.clear();
}
